{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "using LinearAlgebra"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "rankrsvd (generic function with 1 method)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function fullsvd(A) \n",
    "    U,s,V = svd(A, full = true)  # compute svd\n",
    "    Σ = zeros(size(A))           # container for Σ  \n",
    "    for i=1:length(s)\n",
    "       Σ[i,i] = s[i]            # place singular values in Σ\n",
    "    end                      # a practical svd would never store all these zeros\n",
    "    display(U);display(Σ);display(V) # display the answer\n",
    "    return(U,Σ,V)                # return the answer\n",
    "end\n",
    "\n",
    "\n",
    "function rankrsvd(A) \n",
    "    U,s,V = svd(A, full = true)  # compute svd\n",
    "    r = sum(s.>1e-8)             # rank = how many positive?\n",
    "    U₁ = U[:,1:r]\n",
    "    Σᵣ = Diagonal(s[1:r])        # Diagonal matrix of singular values\n",
    "    V₁ = V[:,1:r]\n",
    "    display(U₁);display(Σᵣ);display(V₁) # display the answer\n",
    "    return(U₁,Σᵣ,V₁)                # return the answer\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. random 2x2 matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " 0.259439  0.075927\n",
       " 0.898109  0.918728"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = rand(2,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.18222   -0.983258\n",
       " -0.983258   0.18222 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " 1.30643  0.0    \n",
       " 0.0      0.13025"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Adjoint{Float64,Array{Float64,2}}:\n",
       " -0.712128  -0.70205 \n",
       " -0.70205    0.712128"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fullsvd(A);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.18222   -0.983258\n",
       " -0.983258   0.18222 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Diagonal{Float64,Array{Float64,1}}:\n",
       " 1.30643   ⋅     \n",
       "  ⋅       0.13025"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.712128  -0.70205 \n",
       " -0.70205    0.712128"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rankrsvd(A);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. random 3x2 matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×2 Array{Float64,2}:\n",
       " 0.464581  0.051883\n",
       " 0.9702    0.533329\n",
       " 0.601868  0.413574"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = rand(3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3 Array{Float64,2}:\n",
       " -0.311792   0.90137     0.300529\n",
       " -0.794641  -0.0739732  -0.602555\n",
       " -0.520894  -0.426685    0.73933 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3×2 Array{Float64,2}:\n",
       " 1.39313  0.0     \n",
       " 0.0      0.191691\n",
       " 0.0      0.0     "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Adjoint{Float64,Array{Float64,2}}:\n",
       " -0.882421   0.47046 \n",
       " -0.47046   -0.882421"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fullsvd(A);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×2 Array{Float64,2}:\n",
       " -0.311792   0.90137  \n",
       " -0.794641  -0.0739732\n",
       " -0.520894  -0.426685 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Diagonal{Float64,Array{Float64,1}}:\n",
       " 1.39313   ⋅      \n",
       "  ⋅       0.191691"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.882421   0.47046 \n",
       " -0.47046   -0.882421"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rankrsvd(A);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. random 2x3 matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×3 Array{Float64,2}:\n",
       " 0.0451975  0.242917  0.405185\n",
       " 0.477637   0.8663    0.725397"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = rand(2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.337277  -0.941405\n",
       " -0.941405   0.337277"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×3 Array{Float64,2}:\n",
       " 1.30125  0.0       0.0\n",
       " 0.0      0.191821  0.0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3×3 Adjoint{Float64,Array{Float64,2}}:\n",
       " -0.357268   0.618008  -0.700304\n",
       " -0.689699   0.331038   0.643994\n",
       " -0.629821  -0.713078  -0.30797 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fullsvd(A);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Float64,2}:\n",
       " -0.337277  -0.941405\n",
       " -0.941405   0.337277"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "2×2 Diagonal{Float64,Array{Float64,1}}:\n",
       " 1.30125   ⋅      \n",
       "  ⋅       0.191821"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3×2 Array{Float64,2}:\n",
       " -0.357268   0.618008\n",
       " -0.689699   0.331038\n",
       " -0.629821  -0.713078"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rankrsvd(A);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. rank 3, 7x10 matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7×10 Array{Float64,2}:\n",
       " 0.409585  0.550866  0.729917  0.396048  …  0.491844  0.870667  0.327258\n",
       " 0.824315  0.457974  0.887333  0.932895     0.34797   1.19361   0.266938\n",
       " 0.897034  0.338666  0.678985  0.943025     0.418739  1.0996    0.258406\n",
       " 0.862495  0.661816  0.926009  0.816466     0.771865  1.33408   0.463019\n",
       " 0.878864  0.887087  1.42046   0.99785      0.602456  1.66596   0.472172\n",
       " 0.765583  0.423397  0.731421  0.800129  …  0.446203  1.06758   0.287248\n",
       " 0.710849  0.713791  1.12556   0.793167     0.511149  1.33563   0.388595"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = rand(7,3)*rand(3,10) # this should be rank 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7×7 Array{Float64,2}:\n",
       " -0.277937  -0.522311   -0.0744039  …   0.466151  -0.560653    0.264395   \n",
       " -0.34423    0.518096   -0.0720404     -0.227442  -0.460716   -0.319634   \n",
       " -0.335511   0.428918    0.464644       0.604044   0.0486161  -0.0705107  \n",
       " -0.436358  -0.497343    0.506287      -0.350516   0.117976   -0.410459   \n",
       " -0.487624   0.0167782  -0.553854      -0.204899  -0.105282   -0.000703896\n",
       " -0.327734   0.157075    0.264594   …  -0.34661    0.116364    0.806582   \n",
       " -0.395088  -0.0499189  -0.374552       0.284817   0.657649   -0.0625039  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "7×10 Array{Float64,2}:\n",
       " 6.92226  0.0       0.0       0.0          …  0.0          0.0  0.0  0.0\n",
       " 0.0      0.755198  0.0       0.0             0.0          0.0  0.0  0.0\n",
       " 0.0      0.0       0.683053  0.0             0.0          0.0  0.0  0.0\n",
       " 0.0      0.0       0.0       5.91088e-16     0.0          0.0  0.0  0.0\n",
       " 0.0      0.0       0.0       0.0             0.0          0.0  0.0  0.0\n",
       " 0.0      0.0       0.0       0.0          …  0.0          0.0  0.0  0.0\n",
       " 0.0      0.0       0.0       0.0             8.21229e-17  0.0  0.0  0.0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "10×10 Adjoint{Float64,Array{Float64,2}}:\n",
       " -0.294011   0.35548     0.312083   …   0.0465244    0.0514862   0.039223 \n",
       " -0.2263    -0.249712   -0.334077       0.181558     0.595424    0.0233641\n",
       " -0.363646  -0.0109916  -0.510499      -0.0359443   -0.220601    0.140677 \n",
       " -0.312911   0.500153    0.171036      -0.359502    -0.207792    0.0736223\n",
       " -0.237955  -0.64866     0.255552      -0.601864    -0.131402   -0.104849 \n",
       " -0.251608   0.0397458  -0.437401   …   0.164673    -0.485916   -0.221939 \n",
       " -0.477004  -0.0809271   0.436915       0.478804     0.100636    0.0399163\n",
       " -0.198741  -0.299539    0.17074        0.373694    -0.353637   -0.236875 \n",
       " -0.475836   0.133415   -0.153594      -0.275708     0.389516   -0.22132  \n",
       " -0.137166  -0.156822   -0.0295032      0.00811763  -0.103379    0.897647 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fullsvd(A);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7×3 Array{Float64,2}:\n",
       " -0.277937  -0.522311   -0.0744039\n",
       " -0.34423    0.518096   -0.0720404\n",
       " -0.335511   0.428918    0.464644 \n",
       " -0.436358  -0.497343    0.506287 \n",
       " -0.487624   0.0167782  -0.553854 \n",
       " -0.327734   0.157075    0.264594 \n",
       " -0.395088  -0.0499189  -0.374552 "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "3×3 Diagonal{Float64,Array{Float64,1}}:\n",
       " 6.92226   ⋅         ⋅      \n",
       "  ⋅       0.755198   ⋅      \n",
       "  ⋅        ⋅        0.683053"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "10×3 Array{Float64,2}:\n",
       " -0.294011   0.35548     0.312083 \n",
       " -0.2263    -0.249712   -0.334077 \n",
       " -0.363646  -0.0109916  -0.510499 \n",
       " -0.312911   0.500153    0.171036 \n",
       " -0.237955  -0.64866     0.255552 \n",
       " -0.251608   0.0397458  -0.437401 \n",
       " -0.477004  -0.0809271   0.436915 \n",
       " -0.198741  -0.299539    0.17074  \n",
       " -0.475836   0.133415   -0.153594 \n",
       " -0.137166  -0.156822   -0.0295032"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rankrsvd(A);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "kernelspec": {
   "display_name": "Julia 1.3.0",
   "language": "julia",
   "name": "julia-1.3"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.3.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
